
self.Module = {
    onRuntimeInitialized: function () {

    }
};
self.importScripts("common.js");
// var USE_MISSILE = false;
// var decoder_type;
// var DECODER_TYPE = kDecoder_decodeer_js;
// var DECODER_TYPE = kDecoder_prod_h265_wasm_combine_js;
var webglPlayer, canvas, videoWidth, videoHeight, yLength, uvLength;
var LOG_LEVEL_JS = 0;
var LOG_LEVEL_WASM = 1;
var LOG_LEVEL_FFMPEG = 2;
var DECODER_H264 = 0;
var DECODER_H265 = 1;
 
function Player(){
    this.decoder_type = DECODER_TYPE;//DECODER_H265;
    this.decoding = false;
    this.webrtcplayerState = playerStateIdle;
    this.decodeInterval     = 3; //编码定时器
    this.urgent = false;
    this.destroied = false;
    this.decoderworker=null;
    this.frameBuffer = [];
    // this.Module = {};
}
Player.prototype.setDecoder=function(type) {
    this.decoder_type = type;
}

Player.prototype.startDecoder=function(decoder_type){
    var self = this;
    self.setDecoder(decoder_type);
    switch(decoder_type){
        case kDecoder_decodeer_js:
            self.decoderworker=new Worker("decoder.js");  
            var req = {
                t: kInitDecoderReq,
            };
            self.decoderworker.postMessage(req);
            self.decoderworker.onmessage=function (evt) {
                var objData = evt.data;
                switch (objData.t) {
                    case kInitDecoderRsp:
                        self.onInitDecoder(objData);
                        break;
                    case kOpenDecoderRsp:
                        self.onOpenDecoder(objData);
                        // this.displayLoop();
                        // var req = {
                        //     t: kInitPlayerReq,
                        // };
                        // self.postMessage(req);
                        break;
                    case kVideoFrame:
                        self.onVideoFrame(objData);
                        break;
                    // case kVideoFrame_Missle:
                    //     self.onVideoFrame_Missle(objData);
                    //     break;    
                    // case kprodVideoFrame:
                    //     self.onVideoFrame_Prod(objData);
                    //     break;
                    // case "decode":
                    //     console.log("decode"+objData)
                    //     break;    
                    default:
                        console.log("Unsupport messsage " + req.t);     
                }
            }  
            break;
        // this.decoderworker=new Worker("decoder_missle.js");
        case kDecoder_prod_h265_wasm_combine_js:
            // this.decoderworker=new Worker("prod_decoder.js");  
            self.Module = {};  
            self.decoderworker=new Worker("glue.js");//prod.h265.wasm.combine.js");
            self.SetProdDecoder(self.decoderworker,self);
            break;
        case kDecoder_missile_decoder_js:
            self.decoderworker=new Worker("decoder_missle.js");//prod.h265.wasm.combine.js");
            var req = {
                t: kInitDecoderReq,
            };
            self.decoderworker.postMessage(req);
            console.log("InitMissleDecoder");
            self.decoderworker.onmessage=function (evt) {
                var objData = evt.data;
                switch (objData.t) {
                    case kInitDecoderRsp:
                        self.onInitDecoder(objData);
                        break;
                    case kOpenDecoderRsp:
                        self.onOpenDecoder(objData);
                        // self.displayLoop();
                        // var req = {
                        //     t: kInitPlayerReq,
                        // };
                        // self.postMessage(req);
                        break;
                    case kVideoFrame_Missle:
                        self.onVideoFrame_Missle(objData);
                        break;    
                    default:
                        console.log("Unsupport messsage " + req.t);     
                }
            }
            // this.InitMissleDecoder();
            break;    
        default:
            console.error("not supported");    
        
    }


};
Player.prototype.ReqInitDecoder = function(){
    var req = {
        t: kInitDecoderReq,
    };
    this.decoderworker.postMessage(req);
}
Player.prototype.InitMissleDecoder =function(){
    var req = {
        t: kInitDecoderReq,
    };
    this.decoderworker.postMessage(req);
    console.log("InitMissleDecoder");
    this.decoderworker.onmessage=function (evt) {
        var objData = evt.data;
        switch (objData.t) {
            case kInitDecoderRsp:
                self.onInitDecoder(objData);
                break;
            case kOpenDecoderRsp:
                self.onOpenDecoder(objData);
                // self.displayLoop();
                // var req = {
                //     t: kInitPlayerReq,
                // };
                // this.postMessage(req);
                break;
            case kVideoFrame_Missle:
                self.onVideoFrame_Missle(objData);
                break;    
            default:
                console.log("Unsupport messsage " + req.t);     
        }
    }
}
// Player.prototype.SetDecoder = function (worker,self){
//     var req = {
//         t: kInitDecoderReq,
//     };
//     worker.postMessage(req);
//     worker.onmessage=function (evt) {
//         var objData = evt.data;
//         switch (objData.t) {
//             case kInitDecoderRsp:
//                 self.onInitDecoder(objData);
//                 break;
//             case kOpenDecoderRsp:
//                 self.onOpenDecoder(objData);
//                 break;
//             case kVideoFrame:
//                 self.onVideoFrame(objData);
//                 break;
//             // case kVideoFrame_Missle:
//             //     self.onVideoFrame_Missle(objData);
//             //     break;    
//             case kprodVideoFrame:
//                 self.onVideoFrame_Prod(objData);
//                 break;
//             case "decode":
//                 console.log("decode"+objData)
//                 break;    
//             default:
//                 console.log("Unsupport messsage " + req.t);     
//         }
//     }
// }
Player.prototype.SetProdDecoder = function (worker,self){
    worker.onmessage = function(msg){              // 收到胶水代码返回来的消息的处理方式
        var data = msg.data;
        var decodet1=new Date().getTime();
        console.log(decodet1,"->worker.onmessage",data.type,data.data)
        if(typeof self.onmessage == "function"){
            self.onmessage(data);               // 收到解码器的事件，如果设置了onmessage函数，透传到上层，processor通过这种方式拿到解码器事件
            //data.type
            if(data.type == 'destroy' && typeof self.onterminate == 'function'){
                self.onterminate();
                worker.terminate();
                worker = null;
            }
        }
    }

    worker.onterminate = function(){
        
    }

    this.onmessage = function(data){
        console.log("player onmessage",data.type);
    };
    this.onterminate = function(){
        console.log("playe onterminate");
    };
};

Player.prototype.decode = function(buffer){    // 对外api，解码一段数据
    if(this.decoderworker){
        this.decoderworker.postMessage({
            type: 'decode',
            buffer: buffer,
        });
    }
}

Player.prototype.destroy = function(){         // 对外api，销毁解码器
    this.destroied = true;
    if(this.decoderworker){
        // window.URL.revokeObjectURL(this.url);
        this.decoderworker.postMessage({type: 'destroy'});
    }
}

Player.prototype.startDecoding = function () {
    var req = {
        t: kStartDecodingReq,
        i: this.urgent ? 0 : this.decodeInterval,
    };
    this.decoderworker.postMessage(req);
    this.decoding = true;
    this.webrtcplayerState = playerStatePlaying;
    this.displayLoop();
};

Player.prototype.pauseDecoding = function () {
    var req = {
        t: kPauseDecodingReq
    };
    this.decoderworker.postMessage(req);
    this.decoding = false;
};
Player.prototype.onOpenDecoder=function(objData){
     console.log("reqOpenDecoder response " + objData.e + ".");
    if(objData.e==0){
       this.startDecoding();
    }

}
Player.prototype.onInitDecoder = function (objData) {
  

     console.log("Init decoder response " + objData.e + ".");
    this.reqOpenDecoder();

};
Player.prototype.reqOpenDecoder=function(){
    var req = {
        t: kOpenDecoderReq
    };
    this.decoderworker.postMessage(req);
}
Player.prototype.onFrameData = function (data, len) {
    // console.log("Got data bytes=" + start + "-" + end + ".");
    if(this.decoder_type===kDecoder_prod_h265_wasm_combine_js){
        this.decode(data);
    }else{
        var objData = {
            t: kFeedDataReq,
            d: data
        };
        this.decoderworker.postMessage(objData, [objData.d]);
    }
}
Player.prototype.startBuffering = function () {
    this.buffering = true;
    this.showLoading();
    this.pause();
}

Player.prototype.stopBuffering = function () {
    this.buffering = false;
    this.hideLoading();
    this.resume();
}

Player.prototype.displayVideoFrame = function (frame) {

    var audioTimestamp=0;
    var delay=0
    // console.log("displayVideoFrame delay=" + delay + "=" + " " + frame.s  + " - (" + audioCurTs  + " + " + this.beginTimeOffset + ")" + "->" + audioTimestamp);

    if (audioTimestamp <= 0 || delay <= 0) {
        this.renderVideoFrame(frame.d);
        return true;
    }
    return false;
};

Player.prototype.displayLoop = function() {
    console.log("displayLoop")
    if (this.webrtcplayerState !== playerStateIdle) {
        requestAnimationFrame(this.displayLoop.bind(this));
    }
    if(this.frameBuffer.length>0){
        var frame = this.frameBuffer[0];
        if (this.displayVideoFrame(frame)) {
            this.frameBuffer.shift();
        }
    }
};
Player.prototype.stopDecoder = function() {
     var req={
       t: kPauseDecodingReq,
     }
     this.decoderworker.postMessage(req);
     var req={
        t: kUninitDecoderReq,
      }
      this.decoderworker.postMessage(req);
    //  this.stopBuffering();
     this.webrtcplayerState=playerStateIdle;
};
Player.prototype.renderVideoFrame = function (data) {
    // var self = this;
    var playFrame={
        t: kplayeVideoFrame,
        d: data
    }
    self.postMessage(playFrame,[playFrame.d.data.buffer])

};
Player.prototype.getBufferTimerLength = function() {
    if (!this.frameBuffer || this.frameBuffer.length == 0) {
        return 0;
    }

    let oldest = this.frameBuffer[0];
    let newest = this.frameBuffer[this.frameBuffer.length - 1];
    return newest.s - oldest.s;
};
Player.prototype.bufferFrame = function (frame) {
    // If not decoding, it may be frame before seeking, should be discarded.

    this.frameBuffer.push(frame);
     console.log("bufferFrame pts:" + frame.s+" w:" + frame.d.width + ", h: " + frame.d.height);

}
Player.prototype.onVideoFrame = function (frame) {
    this.bufferFrame(frame);
};
Player.prototype.onVideoFrame_Prod = function (frame) {
    this.bufferFrame(frame);
};
Player.prototype.onVideoFrame_Missle = function (frame) {
    this.bufferFrame(frame);
};
Player.prototype.processReq = function (req) {
    // console.log("processReq " + req.t + ".");
    switch (req.t) {
        case kstartPlayerCoderReq:
            this.startDecoder(req.decoder_type);
            break;
        case kendPlayerCoderReq:
            this.stopDecoder();
            break;
    
        case kInitPlayerReq:
            this.displayLoop();
            break;           
        case ksendPlayerVideoFrameReq:
            this.onFrameData(req.d,req.l);
            break;

        default:
            console.log("Unsupport messsage " + req.t);
    }
};
self.player = new Player;

self.onmessage = function (evt) {
    if (!self.player) {
        console.log("[ER] Player not initialized!");
        return;
    }

    var req = evt.data;


    self.player.processReq(req);
};
